home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-08-27 | 42.4 KB | 1,811 lines |
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v11i024: MS-DOS disk tools for Unix, Part02/02
- Message-ID: <1248@uunet.UU.NET>
- Date: 28 Aug 87 13:09:40 GMT
- Sender: Unknown@uunet.UU.NET
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 1799
- Approved: rs@uunet.UU.NET
-
- Submitted-by: uiucdcs!fthood!egray@harvard.harvard.edu
- Posting-number: Volume 11, Issue 24
- Archive-name: mtools/Part02
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # mkentry.c
- # mmd.c
- # mrd.c
- # mread.c
- # mren.c
- # mtype.c
- # mwrite.c
- # putfat.c
- # search.c
- # subdir.c
- # unixname.c
- # This archive created: Thu Jul 9 22:35:45 1987
- export PATH; PATH=/bin:/usr/bin:$PATH
- echo shar: "extracting 'mkentry.c'" '(2497 characters)'
- if test -f 'mkentry.c'
- then
- echo shar: "will not over-write existing file 'mkentry.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mkentry.c'
- X/*
- X * mk_entry(), grow()
- X */
- X
- X#include <stdio.h>
- X#include <time.h>
- X#include "msdos.h"
- X
- Xextern int fd, dir_start, dir_len, clus_size, dir_entries;
- Xextern int dir_chain[25];
- X
- X/*
- X * Make a directory entry. Builds a directory entry based on the
- X * name, attribute, starting cluster number, and size. Returns a pointer
- X * to the directory structure.
- X */
- X
- Xstruct directory *
- Xmk_entry(filename, attr, fat, size)
- Xchar *filename;
- Xunsigned char attr;
- Xint fat;
- Xint size;
- X{
- X long clock, time();
- X int i;
- X char *strncpy();
- X static struct directory ndir;
- X struct tm *now, *localtime();
- X unsigned char hour, min_hi, min_low, sec;
- X unsigned char year, month_hi, month_low, day;
- X
- X time(&clock);
- X now = localtime(&clock);
- X strncpy(ndir.name, filename, 8);
- X strncpy(ndir.ext, filename+8, 3);
- X ndir.attr = attr;
- X for (i=0; i<10; i++)
- X ndir.reserved[i] = NULL;
- X hour = now->tm_hour << 3;
- X min_hi = now->tm_min >> 3;
- X min_low = now->tm_min << 5;
- X sec = 0;
- X ndir.time[1] = hour + min_hi;
- X ndir.time[0] = min_low + sec;
- X year = (now->tm_year - 80) << 1;
- X month_hi = (now->tm_mon+1) >> 3;
- X month_low = (now->tm_mon+1) << 5;
- X day = now->tm_mday;
- X ndir.date[1] = year + month_hi;
- X ndir.date[0] = month_low + day;
- X ndir.start[1] = fat / 0x100;
- X ndir.start[0] = fat % 0x100;
- X ndir.size[3] = 0; /* can't be THAT large */
- X ndir.size[2] = size / 0x10000;
- X ndir.size[1] = (size % 0x10000) / 0x100;
- X ndir.size[0] = (size % 0x10000) % 0x100;
- X return(&ndir);
- X}
- X
- X/*
- X * Make a subdirectory grow in length. Only subdirectories (not root)
- X * may grow. Returns a 0 on success or 1 on failure (disk full).
- X */
- X
- Xint
- Xgrow(fat)
- Xint fat;
- X{
- X int i, next, last, getfat(), nextfat(), num, sector, buflen;
- X char tbuf[1024];
- X void perror(), exit();
- X
- X last = nextfat(0);
- X if (last == -1)
- X return(1);
- X
- X while (1) {
- X next = getfat(fat);
- X if (next == -1) {
- X fprintf(stderr, "grow: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (next >= 0xff8)
- X break;
- X fat = next;
- X }
- X /* mark the end of the chain */
- X putfat(fat, last);
- X putfat(last, 0xfff);
- X /* zero the buffer */
- X buflen = clus_size * MSECSIZ;
- X for (i=0; i<buflen; i++)
- X tbuf[i] = NULL;
- X
- X /* write the cluster */
- X sector = (last - 2) * clus_size + dir_start + dir_len;
- X move(sector);
- X if (write(fd, tbuf, buflen) != buflen) {
- X perror("grow: write");
- X exit(1);
- X }
- X /* fix up the globals.... */
- X num = dir_entries / 16;
- X dir_entries += clus_size * 16;
- X dir_chain[num] = sector;
- X if (clus_size == 2)
- X dir_chain[num+1] = sector +1;
- X return(0);
- X}
- SHAR_EOF
- if test 2497 -ne "`wc -c < 'mkentry.c'`"
- then
- echo shar: "error transmitting 'mkentry.c'" '(should have been 2497 characters)'
- fi
- fi
- echo shar: "extracting 'mmd.c'" '(3672 characters)'
- if test -f 'mmd.c'
- then
- echo shar: "will not over-write existing file 'mmd.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mmd.c'
- X/*
- X * Make a MSDOS sub directory
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int entry, slot, fat, dot, subdir();
- X char *filename, *newfile, *fixname(), *strncpy(), *unixname();
- X char *getpath(), *pathname, tname[9], text[4], *fixed;
- X void exit();
- X struct directory *dir, *search(), *mk_entry();
- X
- X if (init(2)) {
- X fprintf(stderr, "mmd: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* only 1 directory ! */
- X if (argc != 2) {
- X fprintf(stderr, "Usage: mmd <MSDOS directory>\n");
- X exit(1);
- X }
- X fixed = fixname(argv[1]);
- X filename = unixname(fixed, fixed+8);
- X pathname = getpath(argv[1]);
- X if (strcmp(fixed+8, " ")) {
- X fprintf(stderr, "mmd: Directory names cannot have extensions\n");
- X exit(1);
- X }
- X if (subdir(pathname))
- X exit(1);
- X /* see if exists and get slot */
- X slot = -1;
- X dot = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL) {
- X if (slot < 0)
- X slot = entry;
- X break;
- X }
- X /* if erased */
- X if (dir->name[0] == 0xe5) {
- X if (slot < 0)
- X slot = entry;
- X continue;
- X }
- X /* if not a directory */
- X if (!(dir->attr & 0x10))
- X continue;
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X /* save the 'dot' directory info */
- X if (!strcmp(".", newfile))
- X dot = dir->start[1]*0x100 + dir->start[0];
- X
- X if (!strcmp(filename, newfile)) {
- X fprintf(stderr, "mmd: Directory '%s' already exists\n", filename);
- X exit(1);
- X }
- X }
- X /* no '.' entry means root directory */
- X if (dot == 0 && slot < 0) {
- X printf(stderr, "mmd: No directory slots\n");
- X exit(1);
- X }
- X /* make the directory grow */
- X if (dot && slot < 0) {
- X if (grow(dot)) {
- X fprintf(stderr, "mmd: Disk full\n");
- X exit(1);
- X }
- X /* first slot in 'new' directory */
- X slot = entry;
- X }
- X fat = nextfat(0);
- X if (fat == -1) {
- X fprintf(stderr, "mmd: Disk full\n");
- X exit(1);
- X }
- X /* make directory entry */
- X dir = mk_entry(fixed, 0x10, fat, 0);
- X if (dir != NULL) {
- X writedir(slot, dir);
- X /* write the cluster */
- X putfat(fat, 0xfff);
- X putcluster(fat, dot);
- X }
- X /* write FAT sectors */
- X writefat();
- X close(fd);
- X exit(0);
- X}
- X
- Xputcluster(dot, dot_dot) /* write the cluster */
- Xint dot;
- Xint dot_dot;
- X{
- X long start;
- X void exit(), perror();
- X int buflen;
- X static struct directory dirs[32];
- X struct directory *mk_entry();
- X
- X start = (dot - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X /* make the '.' and '..' entries */
- X dirs[0] = *mk_entry(". ", 0x10, dot, 0);
- X dirs[1] = *mk_entry(".. ", 0x10, dot_dot, 0);
- X
- X if (write(fd, (char *) &dirs[0], buflen) != buflen) {
- X perror("putcluster: write");
- X exit(1);
- X }
- X return;
- X}
- X
- Xint
- Xnextfat(last) /* returns next free cluster */
- Xint last;
- X{
- X static int i;
- X
- X for (i=last+1; i<num_clus+2; i++) {
- X if (!getfat(i))
- X return(i);
- X }
- X return(-1);
- X}
- SHAR_EOF
- if test 3672 -ne "`wc -c < 'mmd.c'`"
- then
- echo shar: "error transmitting 'mmd.c'" '(should have been 3672 characters)'
- fi
- fi
- echo shar: "extracting 'mrd.c'" '(3148 characters)'
- if test -f 'mrd.c'
- then
- echo shar: "will not over-write existing file 'mrd.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mrd.c'
- X/*
- X * Delete a MSDOS sub directory
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int ismatch, entry, start, isempty();
- X char *filename, *newfile, text[4], tname[9], *getname();
- X char *strncpy(), *pathname, *getpath(), *unixname();
- X void exit();
- X struct directory *dir, *search();
- X
- X if (init(2)) {
- X fprintf(stderr, "mrd: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* only 1 directory ! */
- X if (argc != 2) {
- X fprintf(stderr, "Usage: mrd <MSDOS directory>\n");
- X exit(1);
- X }
- X
- X filename = getname(argv[1]);
- X pathname = getpath(argv[1]);
- X if (subdir(pathname))
- X exit(1);
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if not dir */
- X if (!(dir->attr & 0x10))
- X continue;
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X if (!strcmp(newfile, filename)) {
- X start = dir->start[1]*0x100 + dir->start[0];
- X if (!isempty(start)) {
- X fprintf(stderr, "mrd: Directory '%s' is not empty\n", filename);
- X exit(1);
- X }
- X if (!start) {
- X fprintf(stderr, "mrd: Can't remove root directory\n");
- X exit(1);
- X }
- X zapit(start);
- X dir->name[0] = 0xe5;
- X writedir(entry, dir);
- X ismatch = 1;
- X }
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mrd: Directory '%s' not found\n", filename);
- X exit(1);
- X }
- X /* update the FAT sectors */
- X writefat();
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * See if directory is empty. Returns 1 if empty, 0 if not. Can't use
- X * subdir() and search() as it would clobber the globals.
- X */
- X
- Xint
- Xisempty(fat)
- Xint fat;
- X{
- X int i, next, buflen, sector, getfat();
- X unsigned char tbuf[1024];
- X void perror(), exit();
- X
- X while (1) {
- X sector = (fat-2)*clus_size + dir_start + dir_len;
- X move(sector);
- X buflen = clus_size * MSECSIZ;
- X if (read(fd, tbuf, buflen) != buflen) {
- X perror("isempty: read");
- X exit(1);
- X }
- X /* check first character of name */
- X for (i=0; i<MSECSIZ; i+=MDIRSIZ) {
- X if (tbuf[i] == '.')
- X continue;
- X if (tbuf[i] != NULL && tbuf[i] != 0xe5)
- X return(0);
- X }
- X /* get next cluster number */
- X next = getfat(fat);
- X if (next == -1) {
- X fprintf(stderr, "isempty: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (next >= 0xff8)
- X break;
- X fat = next;
- X }
- X return(1);
- X}
- SHAR_EOF
- if test 3148 -ne "`wc -c < 'mrd.c'`"
- then
- echo shar: "error transmitting 'mrd.c'" '(should have been 3148 characters)'
- fi
- fi
- echo shar: "extracting 'mread.c'" '(4523 characters)'
- if test -f 'mread.c'
- then
- echo shar: "will not over-write existing file 'mread.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mread.c'
- X/*
- X * Read (copy) a MSDOS file to Unix
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xlong size;
- Xlong current;
- Xint textmode = 0;
- Xint nowarn = 0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int fat, i, ismatch, entry, subdir(), single, c, oops;
- X char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
- X char *strncpy(), *pathname, *getpath(), *target, *tmp, *malloc();
- X char *strcat(), *strcpy();
- X void perror(), exit();
- X struct directory *dir, *search();
- X struct stat stbuf;
- X
- X if (init(0)) {
- X fprintf(stderr, "mread: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* get command line options */
- X oops = 0;
- X while ((c = getopt(argc, argv, "tn")) != EOF) {
- X switch(c) {
- X case 't':
- X textmode = 1;
- X break;
- X case 'n':
- X nowarn = 1;
- X break;
- X default:
- X oops = 1;
- X break;
- X }
- X }
- X
- X if (oops || (argc - optind) < 2) {
- X fprintf(stderr, "Usage: mread [-t|-n] <MSDOS file> <Unix file>\n");
- X fprintf(stderr, " or mread [-t|-n] <MSDOS file> [<MSDOS files...>] <Unix directory>\n");
- X exit(1);
- X }
- X /* only 1 file to copy... */
- X single = 1;
- X target = argv[argc-1];
- X /* ...unless last arg is a directory */
- X if (!stat(target, &stbuf)) {
- X if (stbuf.st_mode & 040000)
- X single = 0;
- X }
- X
- X for (i=optind; i<argc-1; i++) {
- X filename = getname(argv[i]);
- X pathname = getpath(argv[i]);
- X if (subdir(pathname))
- X continue;
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if dir or volume lable */
- X if ((dir->attr & 0x10) || (dir->attr & 0x08))
- X continue;
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X fat = dir->start[1]*0x100 + dir->start[0];
- X size = dir->size[2]*0x10000 + dir->size[1]*0x100 + dir->size[0];
- X /* if single file */
- X if (single) {
- X if (!strcmp(newfile, filename)) {
- X readit(fat, target);
- X ismatch = 1;
- X break;
- X }
- X }
- X /* if multiple files */
- X else {
- X if (match(newfile, filename)) {
- X printf("Copying %s\n", newfile);
- X tmp = malloc(strlen(target)+1+strlen(newfile)+1);
- X strcpy(tmp, target);
- X strcat(tmp, "/");
- X strcat(tmp, newfile);
- X readit(fat, tmp);
- X ismatch = 1;
- X }
- X }
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mread: File '%s' not found\n", filename);
- X continue;
- X }
- X }
- X close(fd);
- X exit(0);
- X}
- X
- Xreadit(fat, target)
- Xint fat;
- Xchar *target;
- X{
- X char ans[10];
- X void exit();
- X FILE *fp;
- X
- X current = 0L;
- X if (!nowarn) {
- X if (!access(target, 0)) {
- X while (1) {
- X printf("File '%s' exists, overwrite (y/n) ? ", target);
- X gets(ans);
- X if (ans[0] == 'n' || ans[0] == 'N')
- X return;
- X if (ans[0] == 'y' || ans[0] == 'Y')
- X break;
- X }
- X }
- X }
- X
- X if (!(fp = fopen(target, "w"))) {
- X fprintf(stderr, "mread: Can't open '%s' for write\n", target);
- X return;
- X }
- X
- X while (1) {
- X getcluster(fat, fp);
- X /* get next cluster number */
- X fat = getfat(fat);
- X if (fat == -1) {
- X fprintf(stderr, "mread: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (fat >= 0xff8)
- X break;
- X }
- X fclose(fp);
- X return;
- X}
- X
- Xgetcluster(num, fp) /* read a cluster */
- Xint num;
- XFILE *fp;
- X{
- X int i, buflen, start;
- X void exit(), perror();
- X char buf[1024];
- X
- X start = (num - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X if (read(fd, buf, buflen) != buflen) {
- X perror("getcluster: read");
- X exit(1);
- X }
- X /* stop at size not EOF marker */
- X for (i=0; i<buflen; i++) {
- X current++;
- X if (current > size)
- X break;
- X if (textmode && buf[i] == '\r')
- X continue;
- X fputc(buf[i], fp);
- X }
- X return;
- X}
- SHAR_EOF
- if test 4523 -ne "`wc -c < 'mread.c'`"
- then
- echo shar: "error transmitting 'mread.c'" '(should have been 4523 characters)'
- fi
- fi
- echo shar: "extracting 'mren.c'" '(2628 characters)'
- if test -f 'mren.c'
- then
- echo shar: "will not over-write existing file 'mren.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mren.c'
- X/*
- X * Rename an existing MSDOS file
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int entry, ismatch, subdir(), nogo, isdir();
- X char *filename, *newfile, *fixname(), *strncpy(), *unixname();
- X char *getpath(), *pathname, tname[9], text[4], *getname(), *target;
- X char *new, ans[10], *temp, *strcpy();
- X void exit();
- X struct directory *dir, *search();
- X
- X if (init(2)) {
- X fprintf(stderr, "mren: Cannot initialize diskette\n");
- X exit(1);
- X }
- X if (argc != 3) {
- X fprintf(stderr, "Usage: mren <MSDOS source file> <MSDOS target file>\n");
- X exit(1);
- X }
- X filename = getname(argv[1]);
- X pathname = getpath(argv[1]);
- X if (subdir(pathname))
- X exit(1);
- X
- X temp = getname(argv[2]);
- X target = fixname(argv[2]);
- X if (isdir(filename) && strcmp(target+8, " ")) {
- X strcpy(target+8, " ");
- X fprintf(stderr, "mren: Directory names may not have extentions\n");
- X }
- X new = unixname(target, target+8);
- X nogo = 0;
- X /* the name supplied may be altered */
- X if (strcmp(temp, new)) {
- X while (!nogo) {
- X printf("Do you accept '%s' as the new file name (y/n) ? ", new);
- X gets(ans);
- X if (ans[0] == 'y' || ans[0] == 'Y')
- X break;
- X if (ans[0] == 'n' || ans[0] == 'N')
- X nogo = 1;
- X }
- X }
- X if (nogo)
- X exit(0);
- X /* see if exists and do it */
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* you may rename a directory */
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X if (!strcmp(filename, newfile)) {
- X ismatch = 1;
- X strncpy(dir->name, target, 8);
- X strncpy(dir->ext, target+8, 3);
- X writedir(entry, dir);
- X }
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mren: File '%s' not found\n", filename);
- X exit(1);
- X }
- X close(fd);
- X exit(0);
- X}
- SHAR_EOF
- if test 2628 -ne "`wc -c < 'mren.c'`"
- then
- echo shar: "error transmitting 'mren.c'" '(should have been 2628 characters)'
- fi
- fi
- echo shar: "extracting 'mtype.c'" '(3364 characters)'
- if test -f 'mtype.c'
- then
- echo shar: "will not over-write existing file 'mtype.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mtype.c'
- X/*
- X * Display contents of a MSDOS file
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xlong size;
- Xlong current;
- Xstripmode = 0;
- Xtextmode = 0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int fat, i, ismatch, entry, subdir(), c, oops;
- X char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
- X char *strncpy(), *pathname, *getpath();
- X void exit();
- X struct directory *dir, *search();
- X
- X if (init(0)) {
- X fprintf(stderr, "mtype: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* get command line options */
- X oops = 0;
- X while ((c = getopt(argc, argv, "st")) != EOF) {
- X switch(c) {
- X case 's':
- X stripmode = 1;
- X break;
- X case 't':
- X textmode = 1;
- X break;
- X default:
- X oops = 1;
- X break;
- X }
- X }
- X
- X if (oops || (argc - optind) < 1) {
- X fprintf(stderr, "Usage: mtype [-s|-t] <MSDOS file> [<MSDOS files...>]\n");
- X exit(1);
- X }
- X
- X for (i=optind; i<argc; i++) {
- X filename = getname(argv[i]);
- X pathname = getpath(argv[i]);
- X if (subdir(pathname))
- X continue;
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if dir or volume lable */
- X if ((dir->attr & 0x10) || (dir->attr & 0x08))
- X continue;
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X /* see it if matches the pattern */
- X if (match(newfile, filename)) {
- X fat = dir->start[1]*0x100 + dir->start[0];
- X size = dir->size[2]*0x10000 + dir->size[1]*0x100 + dir->size[0];
- X readit(fat);
- X ismatch = 1;
- X }
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mtype: File '%s' not found\n", filename);
- X continue;
- X }
- X }
- X close(fd);
- X exit(0);
- X}
- X
- Xreadit(fat)
- Xint fat;
- X{
- X current = 0L;
- X
- X while (1) {
- X getcluster(fat);
- X /* get next cluster number */
- X fat = getfat(fat);
- X if (fat == -1) {
- X fprintf(stderr, "mtype: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (fat >= 0xff8)
- X break;
- X }
- X return;
- X}
- X
- Xgetcluster(num) /* read a cluster */
- Xint num;
- X{
- X int i, buflen, start;
- X void exit(), perror();
- X char buf[1024];
- X
- X start = (num - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X if (read(fd, buf, buflen) != buflen) {
- X perror("getcluster: read");
- X exit(1);
- X }
- X /* stop at size not EOF marker */
- X for (i=0; i<buflen; i++) {
- X current++;
- X if (current > size)
- X break;
- X if (textmode & buf[i] == '\r')
- X continue;
- X if (stripmode)
- X putchar(buf[i] & 0x7f);
- X else
- X putchar(buf[i]);
- X }
- X return;
- X}
- SHAR_EOF
- if test 3364 -ne "`wc -c < 'mtype.c'`"
- then
- echo shar: "error transmitting 'mtype.c'" '(should have been 3364 characters)'
- fi
- fi
- echo shar: "extracting 'mwrite.c'" '(7067 characters)'
- if test -f 'mwrite.c'
- then
- echo shar: "will not over-write existing file 'mwrite.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'mwrite.c'
- X/*
- X * Write (copy) a Unix file to MSDOS
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xint full = 0;
- Xint textmode = 0;
- Xint nowarn = 0;
- Xint filesize;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int i, entry, ismatch, nogo, slot, start, dot, subdir(), single;
- X int isdir(), root, c, oops;
- X char *filename, *newfile, tname[9], text[4], *fixname(), *getname();
- X char *unixname(), ans[10], *strncpy(), *pathname, *getpath(), *fixed;
- X char *tmp, *malloc(), *strcat(), *strcpy();
- X void exit();
- X struct directory *dir, *search(), *writeit();
- X
- X if (init(2)) {
- X fprintf(stderr, "mwrite: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* get command line options */
- X oops = 0;
- X while ((c = getopt(argc, argv, "tn")) != EOF) {
- X switch(c) {
- X case 't':
- X textmode = 1;
- X break;
- X case 'n':
- X nowarn = 1;
- X break;
- X default:
- X oops = 1;
- X break;
- X }
- X }
- X
- X if (oops || (argc - optind) < 2) {
- X fprintf(stderr, "Usage: mwrite [-t|-n] <Unix file> <MSDOS file>\n");
- X fprintf(stderr, " or mwrite [-t|-n] <Unix file> [<Unix files...>] <MSDOS directory>\n");
- X exit(1);
- X }
- X root = 0;
- X if (!strcmp(argv[argc-1], "/") || !strcmp(argv[argc-1], "\\"))
- X root = 1;
- X filename = getname(argv[argc-1]);
- X pathname = getpath(argv[argc-1]);
- X /* test if path is ok first */
- X if (subdir(pathname))
- X exit(1);
- X /* test if last argv is a dir */
- X if (isdir(filename) || root) {
- X if (!strlen(pathname)) {
- X /* don't alter the presence or */
- X /* absence of a leading separator */
- X tmp = malloc(strlen(filename)+1);
- X strcpy(tmp, filename);
- X }
- X else {
- X tmp = malloc(strlen(pathname)+1+strlen(filename)+1);
- X strcpy(tmp, pathname);
- X strcat(tmp, "/");
- X strcat(tmp, filename);
- X }
- X /* subdir is not recursive */
- X subdir(tmp);
- X single = 0;
- X }
- X else
- X single = 1;
- X
- X for (i=optind; i<argc-1; i++) {
- X if (single) {
- X fixed = fixname(argv[argc-1]);
- X filename = unixname(fixed, fixed+8);
- X }
- X else {
- X fixed = fixname(argv[i]);
- X filename = unixname(fixed, fixed+8);
- X printf("Copying %s\n", filename);
- X }
- X /* see if exists and get slot */
- X ismatch = 0;
- X slot = -1;
- X dot = 0;
- X nogo = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* is empty */
- X if (dir->name[0] == NULL) {
- X if (slot < 0)
- X slot = entry;
- X break;
- X }
- X /* is erased */
- X if (dir->name[0] == 0xe5) {
- X if (slot < 0)
- X slot = entry;
- X continue;
- X }
- X strncpy(tname, dir->name, 8);
- X strncpy(text, dir->ext, 3);
- X newfile = unixname(tname, text);
- X /* save the '.' entry info */
- X if ((dir->attr & 0x10) && !strcmp(".", newfile)) {
- X dot = dir->start[1]*0x100 + dir->start[0];
- X continue;
- X }
- X /* is dir or volume lable */
- X if ((dir->attr & 0x10) || (dir->attr & 0x08))
- X continue;
- X /* if file exists, delete it first */
- X if (!strcmp(filename, newfile)) {
- X ismatch = 1;
- X start = dir->start[1]*0x100 + dir->start[0];
- X if (nowarn) {
- X zapit(start);
- X dir->name[0] = 0xe5;
- X writedir(entry, dir);
- X if (slot < 0)
- X slot = entry;
- X } else {
- X while (1) {
- X printf("File '%s' exists, overwrite (y/n) ? ", filename);
- X gets(ans);
- X if (ans[0] == 'n' || ans[0] == 'N') {
- X nogo = 1;
- X break;
- X }
- X if (ans[0] == 'y' || ans[0] == 'Y') {
- X zapit(start);
- X dir->name[0] = 0xe5;
- X writedir(entry, dir);
- X if (slot < 0)
- X slot = entry;
- X break;
- X }
- X }
- X }
- X }
- X if (ismatch)
- X break;
- X }
- X if (nogo) /* chickened out... */
- X continue;
- X /* no '.' entry means root directory */
- X if (dot == 0 && slot < 0) {
- X printf(stderr, "mwrite: No directory slots\n");
- X exit(1);
- X }
- X /* make the directory grow */
- X if (dot && slot < 0) {
- X if (grow(dot)) {
- X fprintf(stderr, "mwrite: Disk full\n");
- X exit(1);
- X }
- X /* first entry in 'new' directory */
- X slot = entry;
- X }
- X /* write the file */
- X dir = writeit(fixed, argv[i]);
- X if (dir != NULL)
- X writedir(slot, dir);
- X
- X if (full) {
- X fprintf(stderr, "mwrite: Disk Full\n");
- X break;
- X }
- X if (single)
- X break;
- X }
- X /* write FAT sectors */
- X writefat();
- X close(fd);
- X exit(0);
- X}
- X
- Xstruct directory *
- Xwriteit(fixed, path)
- Xchar *fixed;
- Xchar *path;
- X{
- X FILE *fp;
- X int size, fat, firstfat, oldfat, nextfat(), putcluster(), putfat();
- X struct directory *mk_entry();
- X static struct directory *dir;
- X struct stat stbuf;
- X
- X if (stat(path, &stbuf) < 0) {
- X fprintf(stderr, "mwrite: Can't stat '%s'\n", path);
- X return(NULL);
- X }
- X filesize = stbuf.st_size;
- X if (!(fp = fopen(path, "r"))) {
- X fprintf(stderr, "mwrite: Can't open '%s' for read\n", path);
- X return(NULL);
- X }
- X size = 0;
- X firstfat = nextfat(0);
- X if (firstfat == -1) {
- X full = 1;
- X return(NULL);
- X }
- X fat = firstfat;
- X while (1) {
- X size += putcluster(fat, fp);
- X if (size >= filesize) {
- X putfat(fat, 0xfff);
- X break;
- X }
- X oldfat = fat;
- X /* get next free cluster */
- X fat = nextfat(oldfat);
- X if (fat == -1) {
- X putfat(oldfat, 0xfff);
- X full = 1;
- X break;
- X }
- X putfat(oldfat, fat);
- X }
- X fclose(fp);
- X dir = mk_entry(fixed, 0, firstfat, size);
- X return(dir);
- X}
- X
- Xint
- Xputcluster(num, fp) /* write to a cluster */
- Xint num;
- XFILE *fp;
- X{
- X long start;
- X void exit(), perror();
- X int buflen, c;
- X static int current;
- X char tbuf[1024];
- X
- X start = (num - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X /* '\n' to '\r\n' translation */
- X if (textmode) {
- X current = 0;
- X while (current < buflen) {
- X if ((c = fgetc(fp)) == EOF) {
- X /* put a file EOF marker */
- X tbuf[current] = 0x1a;
- X break;
- X }
- X if (c == '\n') {
- X tbuf[current++] = '\r';
- X if (current == buflen)
- X break;
- X tbuf[current++] = '\n';
- X /* make the file appear larger */
- X filesize++;
- X }
- X else
- X tbuf[current++] = c;
- X }
- X }
- X else {
- X if ((current = fread(tbuf, sizeof(char), buflen, fp)) < 0) {
- X perror("putcluster: fread");
- X exit(1);
- X }
- X /* all files get an EOF marker */
- X if (current != buflen)
- X tbuf[current+1] = 0x1a;
- X }
- X
- X if (write(fd, tbuf, buflen) != buflen) {
- X perror("putcluster: write");
- X exit(1);
- X }
- X return(current);
- X}
- X
- Xint
- Xnextfat(last) /* returns next free cluster */
- Xint last;
- X{
- X static int i;
- X
- X for (i=last+1; i<num_clus+2; i++) {
- X if (!getfat(i))
- X return(i);
- X }
- X return(-1);
- X}
- SHAR_EOF
- if test 7067 -ne "`wc -c < 'mwrite.c'`"
- then
- echo shar: "error transmitting 'mwrite.c'" '(should have been 7067 characters)'
- fi
- fi
- echo shar: "extracting 'putfat.c'" '(3118 characters)'
- if test -f 'putfat.c'
- then
- echo shar: "will not over-write existing file 'putfat.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'putfat.c'
- X/*
- X * putfat(), writedir(), zapit(), writefat()
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X#undef DUP_FAT
- X
- Xextern int fd, fat_len, dir_chain[25];
- Xextern unsigned char *fatbuf;
- X
- X/*
- X * Puts a code into the FAT table. Is the opposite of getfat(). No
- X * sanity checking is done on the code. Returns a 1 on error.
- X */
- X
- Xint
- Xputfat(num, code)
- Xint num;
- Xunsigned int code;
- X{
- X/*
- X * | byte n | byte n+1 | byte n+2 |
- X * |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
- X * | | | | | | | | | | | | | | | | | | | | | | | | |
- X * | n.0 | n.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
- X * \_____ \____ \______/________/_____ /
- X * ____\______\________/ _____/ ____\_/
- X * / \ \ / / \
- X * | n+1.5 | n.0 | n.5 | n+2.0 | n+2.5 | n+1.0 |
- X * | FAT entry k | FAT entry k+1 |
- X */
- X int start;
- X /* which bytes contain the entry */
- X start = num * 3 / 2;
- X if (start < 0 || start+1 > (fat_len * MSECSIZ))
- X return(1);
- X /* (odd) not on byte boundary */
- X if (num % 2) {
- X *(fatbuf+start) = (*(fatbuf+start) & 0x0f) + ((code << 4) & 0xf0);
- X *(fatbuf+start+1) = (code >> 4) & 0xff;
- X }
- X /* (even) on byte boundary */
- X else {
- X *(fatbuf+start) = code & 0xff;
- X *(fatbuf+start+1) = (*(fatbuf+start+1) & 0xf0) + ((code >> 8) & 0x0f);
- X }
- X return(0);
- X}
- X
- X/*
- X * Write a directory entry. The first argument is the directory entry
- X * number to write to. The second is a pointer to the directory itself.
- X * All errors are fatal.
- X */
- X
- Xwritedir(num, dir)
- Xint num;
- Xstruct directory *dir;
- X{
- X int skip, entry;
- X void exit(), perror();
- X static struct directory dirs[16];
- X /* which sector */
- X skip = dir_chain[num / 16];
- X
- X move(skip);
- X /* read the sector */
- X if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
- X perror("writedir: read");
- X exit(1);
- X }
- X /* which entry in sector */
- X entry = num % 16;
- X /* copy the structure */
- X dirs[entry] = *dir;
- X move(skip);
- X /* write the sector */
- X if (write(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
- X perror("writedir: write");
- X exit(1);
- X }
- X return;
- X}
- X
- X/*
- X * Remove a string of FAT entries (delete the file). The argument is
- X * the beginning of the string. Does not consider the file length, so
- X * if FAT is corrupted, watch out! All errors are fatal.
- X */
- X
- Xzapit(fat)
- Xint fat;
- X{
- X int next;
- X
- X while (1) {
- X /* get next cluster number */
- X next = getfat(fat);
- X /* mark current cluster as empty */
- X if (putfat(fat, 0) || next == -1) {
- X fprintf(stderr, "zapit: FAT problem\n");
- X exit(1);
- X }
- X if (next >= 0xff8)
- X break;
- X fat = next;
- X }
- X return;
- X}
- X
- X/*
- X * Write the FAT table to the disk. Up to now the FAT manipulation has
- X * been done in memory. All errors are fatal. (Might not be too smart
- X * to wait till the end of the program to write the table. Oh well...)
- X */
- X
- Xwritefat()
- X{
- X int buflen;
- X
- X move(1);
- X buflen = fat_len * MSECSIZ;
- X if (write(fd, fatbuf, buflen) != buflen) {
- X perror("writefat: write");
- X exit(1);
- X }
- X#ifdef DUP_FAT
- X /* the duplicate FAT table */
- X if (write(fd, fatbuf, buflen) != buflen) {
- X perror("writefat: write");
- X exit(1);
- X }
- X#endif DUP_FAT
- X return;
- X}
- SHAR_EOF
- if test 3118 -ne "`wc -c < 'putfat.c'`"
- then
- echo shar: "error transmitting 'putfat.c'" '(should have been 3118 characters)'
- fi
- fi
- echo shar: "extracting 'search.c'" '(1075 characters)'
- if test -f 'search.c'
- then
- echo shar: "will not over-write existing file 'search.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'search.c'
- X/*
- X * Search and extract a directory structure. The argument is the
- X * relative directory entry number (no sanity checking). It returns a
- X * pointer to the directory structure at that location. Attempts to
- X * optimize by trying to determine if the buffer needs to be re-read.
- X * A call to writedir() will scribble on the real buffer, so watch out!
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X /* dir_chain contains the list of sectors */
- X /* that make up the current directory */
- Xextern int fd, dir_chain[25];
- X
- Xstruct directory *
- Xsearch(num)
- Xint num;
- X{
- X int skip, entry;
- X void exit(), perror();
- X static int last;
- X static struct directory dirs[16];
- X
- X /* first call disables optimzation */
- X if (num == 0)
- X last = 0;
- X /* which sector */
- X skip = dir_chain[num / 16];
- X /* don't read it if same sector */
- X if (skip != last) {
- X move(skip);
- X /* read the sector */
- X if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
- X perror("mread: read");
- X exit(1);
- X }
- X }
- X last = skip;
- X /* which entry in sector */
- X entry = num % 16;
- X return(&dirs[entry]);
- X}
- SHAR_EOF
- if test 1075 -ne "`wc -c < 'search.c'`"
- then
- echo shar: "error transmitting 'search.c'" '(should have been 1075 characters)'
- fi
- fi
- echo shar: "extracting 'subdir.c'" '(3854 characters)'
- if test -f 'subdir.c'
- then
- echo shar: "will not over-write existing file 'subdir.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'subdir.c'
- X/*
- X * subdir(), getdir(), get_chain(), reset_dir()
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xextern int dir_chain[25], dir_start, dir_len, dir_entries, clus_size;
- Xextern char *mcwd;
- Xstatic char *lastpath;
- X
- X/*
- X * Parse the path names of a sub directory. Both '/' and '\' are
- X * valid separators. However, the use of '\' will force the operator
- X * to use quotes in the command line to protect '\' from the shell.
- X * Returns 1 on error. Attempts to optimize by remembering the last
- X * path it parsed
- X */
- X
- Xsubdir(name)
- Xchar *name;
- X{
- X char *s, *tmp, *path, *malloc(), *strchr(), *strcpy(), *strcat();
- X static int code;
- X int getdir();
- X /* if full pathname */
- X if (*name == '/' || *name == '\\') {
- X tmp = malloc(strlen(name)+1);
- X strcpy(tmp, name);
- X }
- X /* if relative to MCWD */
- X else {
- X if (!strlen(name)) {
- X tmp = malloc(strlen(mcwd)+1);
- X strcpy(tmp, mcwd);
- X }
- X else {
- X tmp = malloc(strlen(mcwd)+1+strlen(name)+1);
- X strcpy(tmp, mcwd);
- X strcat(tmp, "/");
- X strcat(tmp, name);
- X }
- X }
- X /* if paths are same, do nothing */
- X if (!strcmp(tmp, lastpath))
- X return(0);
- X /* not recursive, start at root */
- X reset_dir();
- X lastpath = malloc(strlen(tmp)+1);
- X strcpy(lastpath, tmp);
- X /* zap the leading separator */
- X if (*tmp == '\\' || *tmp == '/')
- X tmp++;
- X for (s = tmp; *s; ++s) {
- X if (*s == '\\' || *s == '/') {
- X path = tmp;
- X *s = NULL;
- X if (getdir(path))
- X return(1);
- X tmp = s+1;
- X }
- X }
- X code = getdir(tmp);
- X return(code);
- X}
- X
- X/*
- X * Find the directory and get the starting cluster. A null directory
- X * is ok. Returns a 1 on error.
- X */
- X
- Xint
- Xgetdir(path)
- Xchar *path;
- X{
- X int entry, start, get_chain();
- X char *newname, *unixname(), *strncpy(), name[9], ext[4];
- X struct directory *dir, *search();
- X
- X /* nothing required */
- X if (*path == NULL)
- X return(0);
- X
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == NULL)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* skip if not a directory */
- X if (!(dir->attr & 0x10))
- X continue;
- X strncpy(name, dir->name, 8);
- X name[8] = NULL;
- X strncpy(ext, dir->ext, 3);
- X ext[3] = NULL;
- X newname = unixname(name, ext);
- X if (!strcmp(newname, path)) {
- X start = dir->start[1]*0x100 + dir->start[0];
- X /* if '..' pointing to root */
- X if (!start && !strcmp(path, "..")) {
- X reset_dir();
- X return(0);
- X }
- X /* fill in the directory chain */
- X dir_entries = get_chain(start) * 16;
- X return(0);
- X }
- X }
- X /* if '.' or '..', must be root */
- X if (!strcmp(path, ".") || !strcmp(path, "..")) {
- X reset_dir();
- X return(0);
- X }
- X fprintf(stderr, "Path component '%s' is not a directory\n", path);
- X return(1);
- X}
- X
- X/*
- X * Fill in the global variable dir_chain. Argument is the starting
- X * cluster number. Info, in this variable is used by search() to
- X * scan a directory. An arbitrary limit of 25 sectors is placed, this
- X * equates to 400 entries. Returns the number of sectors in the chain.
- X */
- X
- Xint
- Xget_chain(num) /* fill the directory chain */
- Xint num;
- X{
- X int next;
- X static int i;
- X void exit();
- X
- X i = 0;
- X while (1) {
- X dir_chain[i] = (num - 2)*clus_size + dir_start + dir_len;
- X /* sectors, not clusters! */
- X if (clus_size == 2) {
- X dir_chain[i+1] = dir_chain[i] + 1;
- X i++;
- X }
- X i++;
- X if (i >= 25) {
- X fprintf(stderr, "get_chain: directory too large\n");
- X exit(1);
- X }
- X /* get next cluster number */
- X next = getfat(num);
- X if (next == -1) {
- X fprintf(stderr, "get_chain: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (next >= 0xff8) {
- X break;
- X }
- X num = next;
- X }
- X return(i);
- X}
- X
- X/*
- X * Reset the global variable dir_chain to the root directory.
- X */
- X
- Xreset_dir()
- X{
- X int i;
- X
- X for (i=0; i<dir_len; i++)
- X dir_chain[i] = dir_start + i;
- X dir_entries = dir_len * 16;
- X /* disable subdir() optimization */
- X lastpath = "\0";
- X return;
- X}
- SHAR_EOF
- if test 3854 -ne "`wc -c < 'subdir.c'`"
- then
- echo shar: "error transmitting 'subdir.c'" '(should have been 3854 characters)'
- fi
- fi
- echo shar: "extracting 'unixname.c'" '(2293 characters)'
- if test -f 'unixname.c'
- then
- echo shar: "will not over-write existing file 'unixname.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'unixname.c'
- X/*
- X * unixname(), getname(), getpath()
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X/*
- X * Get rid of spaces in a MSDOS 'raw' name (one that has come from the
- X * directory structure) so that it can be used for regular expression
- X * matching with a unix file name. Also used to 'unfix' a name that has
- X * been altered by fixname(). Returns a pointer to the unix style name.
- X */
- X
- Xchar *
- Xunixname(name, ext)
- Xchar *name;
- Xchar *ext;
- X{
- X static char *ans;
- X char *s, tname[9], text[4], *strcpy(), *strcat(), *malloc();
- X char *strchr(), *strncpy();
- X
- X strncpy(tname, name, 8);
- X s = strchr(tname, ' ');
- X if (s != NULL)
- X *s = NULL;
- X tname[8] = NULL;
- X
- X strncpy(text, ext, 3);
- X s = strchr(text, ' ');
- X if (s != NULL)
- X *s = NULL;
- X text[3] = NULL;
- X
- X if (*text != NULL) {
- X ans = malloc(strlen(tname)+1+strlen(text)+1);
- X strcpy(ans, tname);
- X strcat(ans, ".");
- X strcat(ans, text);
- X }
- X else {
- X ans = malloc(strlen(tname)+1);
- X strcpy(ans, tname);
- X }
- X return(ans);
- X}
- X
- X/*
- X * Get name component of filename. Translates name to upper case. Returns
- X * pointer to new name. Could be NULL.
- X */
- X
- Xchar *
- Xgetname(name)
- Xchar *name;
- X{
- X char *s, *malloc(), *strcpy(), *strrchr();
- X static char *temp;
- X
- X if (*name == NULL)
- X return(NULL);
- X
- X temp = malloc(strlen(name)+1);
- X strcpy(temp, name);
- X
- X if (s = strrchr(temp, '/'))
- X temp = s+1;
- X if (s = strrchr(temp, '\\'))
- X temp = s+1;
- X
- X for (s = temp; *s; ++s) {
- X if (islower(*s))
- X *s = toupper(*s);
- X }
- X return(temp);
- X}
- X
- X/*
- X * Get the path component of the filename. Translates to upper case.
- X * Returns pointer to path or NULL if no path exist. Doesn't alter
- X * leading separator, always strips trailing separator (unless it is the
- X * path itself).
- X */
- X
- Xchar *
- Xgetpath(name)
- Xchar *name;
- X{
- X char *s, *s1, *malloc(), *strcpy(), *strrchr();
- X static char *temp;
- X
- X if (*name == NULL)
- X return(NULL);
- X
- X temp = malloc(strlen(name)+1);
- X strcpy(temp, name);
- X
- X s = strrchr(temp, '/');
- X s1 = strrchr(temp, '\\');
- X /* if both are NULL , no path */
- X if (s1 == s)
- X return(NULL);
- X /* zap which ever is last separator */
- X if (s1 > s)
- X *s1 = NULL;
- X if (s > s1)
- X *s = NULL;
- X /* translate to upper case */
- X for (s = temp; *s; ++s) {
- X if (islower(*s))
- X *s = toupper(*s);
- X }
- X /* if null, put separator back */
- X if (!strlen(temp))
- X temp = "/";
- X return(temp);
- X}
- SHAR_EOF
- if test 2293 -ne "`wc -c < 'unixname.c'`"
- then
- echo shar: "error transmitting 'unixname.c'" '(should have been 2293 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-
- --
-
- Rich $alz
- Cronus Project, BBN Labs rsalz@bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-